home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / docs / mags / saku09.lha / Teksti / C-kurssi.txt < prev    next >
Text File  |  1994-11-01  |  47KB  |  1,230 lines

  1. 5
  2. 1*
  3.  
  4. {3                        C-ohjelmointikurssi - Osa 1
  5. {3                        ---------------------------
  6.  
  7.                            Ville-Pertti Keinonen
  8.  
  9.  
  10. Ensimmäinen osa: 
  11.  
  12.     - johdantoa 
  13.     - lähdekoodi 
  14.     - kääntäjä
  15.     - muotoilu
  16.     - funktiot, tyypit ja muuttujat alustavasti
  17.     - lauseet, lausekkeet (perus-operaatiot)
  18.     - vertailuoperaattorit, if-rakenne
  19.  
  20.  
  21. {3C-kieli ja muut kielet, eli miksi kannattaa opetella C:tä
  22.  
  23. Alunperin C-kieli on  kehitetty  UNIX-käyttöjärjestelmän  toteutusta  varten
  24. PDP-tietokoneilla. Kieli onnistui kuitenkin siinä määrin hyvin, että  se  on
  25. yleistynyt lähes kaikentyyppisillä tietokonelaitteistoilla. Amigalla C-kieli
  26. on ohjelmointikielistä ehkä merkittävin, koska Amigan  käyttöjärjestelmä  on
  27. suurelta osin sillä kirjoitettu.
  28.  
  29. C-kieli on rakenteellinen ohjelmointikieli. Sen hallinta vaatii enemmän har-
  30. joitusta kuin matalamman tason (esim. assembler) tai korkeamman tason  (Ami-
  31. galla pääasiassa BASICit ja ARexx) kielet, mutta siitä huolimatta sen  opet-
  32. teleminen on vaivan arvoista, sillä C-kielellä on huomattavia  etuja  molem-
  33. piin luokituksiin verrattuna:
  34.  
  35. Matalamman tason kieliin verrattuna C-kieli on vähemmän vaivalloista ja  bu-
  36. gialtista. Ohjelmointi on siis huomattavasti nopeampaa ja mukavampaa. Samoin
  37. mahdollisten bugien määrä on pienempi ja ilmenevien bugien  etsintä  nopeam-
  38. paa, kuin assemblerilla ohjelmoitaessa. Monilla assembleria käyttävillä  oh-
  39. jelmoijilla, jotka eivät osaa C:tä, on vahvasti se käsitys, että C olisi BA-
  40. SICin kaltainen korkean tason kieli ja tuottaisi hidasta koodia.  Totta  on,
  41. että C-kääntäjän tuottama koodi ei ole aivan niin  tehokasta  kuin  vastaava
  42. koodi huolellisesti assemblerilla tehtynä (mihin kuluu  ohjelmoijalta  aikaa
  43. vähintään kymmenkertaisesti enemmän), mutta ero ei  ole  normaalitilanteissa
  44. kovin suuri; se lienee noin 20-30% yksinkertaisilla kääntäjillä ja  vähemmän
  45. sellaisilla, jotka optimoivat  tehokkaasti  tuottamaansa  koodia.  Kuitenkin
  46. joissain poikkeustilanteissa, joissa assemblerissa voisi tehdä  jotain  eri-
  47. koisempia teknisiä optimointeja, voi ero olla niin suuri, että  moni  ohjel-
  48. moija tekee ainakin kyseisen kohdan mieluummin assemblerilla. Mitä  BASICin-
  49. kaltaisuuteen   tulee,    osoittaa    sen    tyyppinen    käsitys    lähinnä
  50. ymmärtämättömyyttä, sillä:
  51.  
  52. Korkeamman tason kieliin verrattuna C tuottaa käännettynä paljon  tehokkaam-
  53. paa koodia, koska sen rakenteet vastaavat hyvin läheisesti sitä, mitä kesku-
  54. syksikkö käytännössä tekee. Korkeamman tason kielet ovat  usein  komentopoh-
  55. jaisia, eivätkä niiden muuttujien tyypit vastaa keskusyksikön  käsittelemiä,
  56. joten jokaista komentoa tai lausekkeen osaa vastaa jokin kokonainen  assemb-
  57. ler-rutiini, joka on useimmiten aivan turhan monimutkainen kyseisen  operaa-
  58. tion suorittamiseen.
  59.  
  60. Amigalle on ilmestynyt uusi, ilmeisesti  C:n  haastajaksi  tarkoitettu  mel-
  61. kein-rakenteellinen ohjelmointikieli, E, joka on helpompaa kuin C  ja  jossa
  62. on nopeampi kääntäjä (joka tosin ei pahemmin optimoi  tuotettua  koodia)  ja
  63. mahdollisuus käyttää helpommin suoraan assemblerkomentoja  koodin  joukossa.
  64. Omasta mielestäni E ei kuitenkaan sovellu oikein mihinkään, paitsi ehkä sel-
  65. laisiin aivan pieniin ohjelmiin, jotka ovat assembleria, lukuunottamatta jo-
  66. tain kutsuja E:n tai käyttöjärjestelmän korkeamman tason rutiineihin.
  67.  
  68.  
  69. {3C-kielen kehitys
  70.  
  71. C-kieli on ajan mittaan muuttunut hieman alkuperäisestä  muodostaan.  Jotkut
  72. asiat ovat olleet epäselviä, ja niiden toiminta  on  vaihdellut  kääntäjästä
  73. toiseen. Tämän vuoksi ANSI (American National Standard for Information  Sys-
  74. tems) loi X3J11:n, teknillisen toimikunnan, jonka tehtävänä  oli  standardi-
  75. soida C-kieli. Tämä standardisoitu muoto C-kielestä tunnetaan nykyisin ylei-
  76. sesti "ANSI C":nä. Muista C:n "määritelmistä" lienee merkittävin K&R  (viit-
  77. taa Brian Kernighanin ja Dennis Ritchien teokseen C-kielestä), johon ANSI  C
  78. osin pohjautuu.
  79.  
  80. Suurin osa Amigan C-kääntäjistä on pääpiirteiltään ANSI C-standardin  mukai-
  81. sia. Useimmiten kuitenkin joitain asioita on laajennettu, ja kääntäjät  ovat
  82. joidenkin asioiden suhteen suvaitsevampia kuin standardin mukaisen kääntäjän
  83. tulisi olla. Tässä kurssissa pyrin parhaiden tietojeni  mukaan  mainitsemaan
  84. kyseisenlaiset poikkeamat niihin liittyvän materiaalin yhteydessä.
  85.  
  86.  
  87. {3Tämä kurssi
  88.  
  89. Tämän kurssin tarkoituksena on selittää C-kielen perusteet ja  antaa  hieman
  90. pitemmällekin menevää tietoa sillä ohjelmoinnista, eli kurssista lienee apua
  91. myös monille sellaisille, jotka jo osaavat C:tä.
  92.  
  93. Pelkkä kurssin lukeminen ei kuitenkaan riitä C-kielen ohjelmointiin:  täytyy
  94. myös pyrkiä ymmärtämään lukemansa, joten  suosittelen,  että  luette  kaiken
  95. huolellisesti ja etenette seuraavaan kohtaan vasta ymmärrettyänne  edellisen
  96. kohdan mahdollisimman hyvin. Muistakaa myös, että kertaus ja  käytännön  ko-
  97. keilut auttavat muistamaan asioita. Tämä kurssi ei  takaa  ohjelmointitaidon
  98. kehittymistä, mutta jos kykenee ymmärtämään sisällön ja näiden tietojen  pe-
  99. rusteella lähtee  rohkeasti  kokeilemaan  ja  harjoittelemaan  ohjelmointia,
  100. pitäisi vähitellen syntyä C-kieleen hyvä tuntuma,  jonka  avulla  voikin  jo
  101. aloittaa varsinaisen ohjelmoinnin.
  102.  
  103. Tämä kurssi ei sinänsä vaadi mitään aiempaa ohjelmointitaitoa, mutta assemb-
  104. lerin jonkinasteinen hallitseminen on hyödyksi, sillä  se  helpottaa  koneen
  105. toiminnan ja joidenkin käsitteiden käytännön merkityksen ymmärtämistä.  Jon-
  106. kinlainen C-kääntäjä on hyvä olla, jotta voi myös kokeilla oppimiaan  asioi-
  107. ta. Amigalle on saatavilla ainakin seuraavia kääntäjiä:
  108.  
  109. {3Aztec (Manx) C
  110.  
  111. Tätä ei  varmaan  enää  moni  käytä.  Aztec  on  vanhanaikainen  (ja  vanha)
  112. kääntäjä, aikoinaan se on ollut ilmeisesti aika suosittukin. En tiedä,  onko
  113. tätä kääntäjää enää mistään saatavilla, enkä näe mitään  syytä,  miksi  joku
  114. haluaisi vielä nykyään käyttää Aztecia.
  115.  
  116. {3DICE C
  117.  
  118. DICE on alunperin Matthew Dillonin sharewarena julkaisema C-kääntäjä.  Uudet
  119. versiot ovat kaupallisia, mutta vapaasti  levitettäviä  versioita  on  vielä
  120. liikkeellä, ja ne ovat ominaisuuksiltaan jo erittäin käyttökelpoisia. Vaikka
  121. koneessa ei olisi paljon muistia, DICE  toimii  hyvin  ja  kääntää  ohjelmat
  122. erittäin nopeasti. DICE:n tuottama koodi on suhteellisen pientä  ja  nopeaa,
  123. vaikka DICE ei suorita  sille  mitään  monimutkaisempia  optimointeja.  Itse
  124. käytän  enimmäkseen  DICE:n   rekisteröityä   shareware-versiota   ohjelmien
  125. kääntämiseen.
  126.  
  127. {3GNU C (eli GCC)
  128.  
  129. GCC on muista järjestelmistä portattu C-kääntäjä, joka on ilmainen (GNU  li-
  130. cense takaa ohjelman olevan täysin ilmainen, vapaasti  käytettävissä,  levi-
  131. tettävissä ja jopa muuteltavissa). GCC kääntää ohjelmia kohtuullisen nopeas-
  132. ti ja optimoi hyvin tehokkaasti, mutta vaatii suhteellisen  paljon  muistia.
  133. GCC:n tuottamat ohjelmat vaativat ixemul.libraryn.  GCC  soveltuu  parhaiten
  134. käytettäväksi   UNIX-tyyppisiä,   helposti   eri   järjestelmille    suoraan
  135. käännettäviä ohjelmia tehtäessä.
  136.  
  137. {3SAS/C (entinen Lattice C)
  138.  
  139. SAS/C on ollut jo pitkään Amigan suosituin C-kääntäjä. SAS/C on kaupallinen,
  140. mutta sen kehitys on lopetettu. SAS/C toimii suhteellisen vähällä  muistilla
  141. ja kääntää kohtuullisen nopeasti, jos optimointi on pois päältä, mutta tuot-
  142. taa erittäin hidasta koodia. Optimoinnin kanssa tuotettu koodi on paljon te-
  143. hokkaampaa, mutta kääntäminen on erittäin hidasta ja muistia  kuluu  monissa
  144. tapauksissa valtavia määriä.
  145.  
  146. Myös joitain pienempiä, ilmaisia kääntäjiä on  saatavilla  (ainakin  PDC  ja
  147. North C), mutta ne ovat vanhoja ja hyvin alkeellisia.
  148.  
  149. Jossain vaiheessa pitäisi ilmestyä Amigalle vielä yksi  merkittävä  ilmainen
  150. C-kääntäjä, joka lienee harkitsemisen  arvoinen.  Olen  nimittäin  itse  te-
  151. kemässä kääntäjää. Toistaiseksi sillä ei ole vielä  nimeä,  mutta  kääntäjän
  152. pääosa on jo varsin pitkällä ja toimii hyvin niin pitkälle kuin sitä on ole-
  153. massa. Generoidun koodin pitäisi olla GCC:n tuottaman  tasoa  (myös  joitain
  154. GCC:n ja muiden kääntäjien  C-laajennuksia,  kuten  case  rangeja  ja  __ty-
  155. peof__:ia,  tuetaan),  mutta  lisäksi   toiminta   soveltuu   hyvin   Amiga-
  156. ympäristöön. Mainostan vain etukäteen, ettei  kannata  välttämättä  ainakaan
  157. ostaa C-kääntäjää, kurssin ajaksi ja muutenkin aloitteluvaiheeseen on DICE:n
  158. ilmaisversio useimmille ehkä paras vaihtoehto. Täydellisempi kääntäjä  olisi
  159. tietysti GCC, joka on hyvä valinta, jos pitää  erityisesti  UNIX-tyyppisistä
  160. ohjelmistoista ja omistaa riittävästi kovalevy- sekä muistitilaa.
  161.  
  162. Kääntäjän lisäksi on tietysti oltava jokin tekstieditori, jolla syöttää  oh-
  163. jelmat koneelle. Tällaisia on varmasti  jokaisen  saatavilla;  Amigan  Work-
  164. bench-diskeillä tulee näitä jo kolme: ed, edit, memacs. Ne riittävät jo  hy-
  165. vin C-ohjelmoinnin opetteluun, mutta pitemmälle päästäessä on  hyvä  hankkia
  166. jokin monipuolisempi (configuroitavuudeltaan) editori.
  167.  
  168. Kurssi pyrkii olemaan mahdollisimman kattava, mutta kuitenkin selkeä. Alussa
  169. joudutaan käyttämään joidenkin asioiden  esittämisessä  esimerkkejä,  joiden
  170. varsinaisen sisällön merkitys selviää vasta myöhemmässä  vaiheessa,  erityi-
  171. sesti koska kurssi pyrkii olemaan "oikeaoppinen" alusta alkaen.
  172.  
  173. Kurssissa käytetyt termit saattavat  poiketa  virallisista  suomenkielisistä
  174. termeistä, koska itse tunnen oikeat termit vain englanniksi. Monet asiat  on
  175. selitetty hieman kierrellen  jonkun  hankalan  tai  oudon  kuuloisen  termin
  176. käytön välttämiseksi. Joissain yhteyksissä on myös  englanninkielinen  termi
  177. mainittu.
  178.  
  179.  
  180. {3Lähdekoodi ja käännös
  181.  
  182. C-kieltä ohjelmoitaessa kirjoitetaan ensin ohjelma tekstieditorilla ja  tal-
  183. lennetaan se tiedostoon. Tätä tiedostoa sanotaan  lähdekoodiksi.  Yleisemmin
  184. käytetään kuitenkin vastaavasta englanninkielisestä termistä  "source  code"
  185. johdettua slanginimitystä  "sorsa".  C-kielen  lähdekooditiedostot  nimetään
  186. yleensä käyttäen päätettä ".c".
  187.  
  188. Jotta ohjelma  saadaan  lähdekoodista  ajettavaksi  tiedostoksi,  täytyy  se
  189. kääntää jollain C-kääntäjällä. Käännöksessä on useita vaiheita, joita  käsi-
  190. tellään myöhemmin. Ohjelmoijan ei yksinkertaisia ohjelmia tehdessä  tarvitse
  191. huomioida eri vaiheita, koska C-kääntäjän liittymäosa osaa  useimmiten  ajaa
  192. kaikki käännöksen vaiheet automaattisesti.
  193.  
  194. Hyvin yleistä on kuitenkin, ettei  kääntäjä  kykene  kääntämään  lähdekoodia
  195. ajettavaksi ohjelmaksi, koska siinä on virheitä. Tällöin kääntäjä  ilmoittaa
  196. virheistä ja kertoo yleensä ainakin virheen  tyypin  sekä  rivin,  jolla  se
  197. lähdekoodissa esiintyy. Kun näin tapahtuu, kannattaa katsoa lähdekoodin  ri-
  198. viä, jolla  kääntäjä  ilmoittaa  virheen  olevan.  Yleensä  virheet,  joista
  199. kääntäjä ilmoittaa, ovat välittömästi näkyvissä olevia (esimerkiksi  kirjoi-
  200. tusvirheitä). Jos kyseiseltä riviltä ei löydy mitään,  mikä  vaikuttaa  vir-
  201. heelliseltä, kannattaa katsoa paria edellistä riviä.
  202.  
  203. Monet kääntäjät eivät yhdestä virheestä keskeytä  käännöstä,  vaan  jatkavat
  204. eteenpäin, jolloin virheitä saatetaan luetella useampia. Useimmat  kääntäjät
  205. saattavat myös varoittaa jostain asioista. Nämä varoitukset eivät ole varsi-
  206. naisia virheitä, ja ohjelma yleensä  kääntyy  varoituksista  huolimatta.  Ne
  207. saattavat kuitenkin tarkoittaa, ettei ohjelma tule toimimaan aivan kunnolla,
  208. eli ohjelman ei pitäisi käännettäessä tuottaa edes varoituksia.
  209.  
  210. Kun ohjelma lopulta kääntyy kunnolla ilman virheitä tai varoituksia, pitäisi
  211. tuloksena olla ajettava tiedosto, jota voi jo kokeilla. Kuitenkaan se,  että
  212. kääntäjä on onnistunut kääntämään ohjelman lähdekoodista ajettavaan muotoon,
  213. ei takaa ohjelman toimivan halutusti. Ohjelmassa voi olla kaikenlaisia suun-
  214. nitteluvirheitä,  "bugeja",  jotka   saattavat   olla   hyvinkin   vaikeasti
  215. löydettävissä. Tällaisten vikojen  etsintää  eli  "debuggausta"  käsitellään
  216. kurssissa vasta myöhemmin, kun on aluksi käyty läpi itse C-kielen perusteet.
  217. Kurssin esimerkkiohjelmien pitäisi kuitenkin toimia millä tahansa  kunnolli-
  218. sella C-kääntäjällä käännettynä. (Niiden esimerkkiohjelmien kohdalla,  joita
  219. tämä ei koske, on erillinen maininta.)
  220.  
  221. Tässä vaiheessa voimmekin jo kokeilla yksinkertaisen  ohjelman  kääntämistä.
  222. Käynnistä tekstieditori ja kirjoita siihen seuraava: 
  223.  
  224. #include <stdio.h>
  225.  
  226. int main(int ac, char **av)
  227. {{
  228.   puts("Hello World!");
  229.   return 0;
  230. }
  231.  
  232. Tallenna ohjelma vaikka tiedostoon nimeltä "hello.c". Tämä hello.c on ohjel-
  233. man lähdekoodi, kuten ylempänä selitettiin. Nyt voidaan kokeilla käyttää  C-
  234. kääntäjää, jotta saadaan tämä hello.c käännettyä ajettavaan muotoon,  vaikka
  235. tiedostoksi nimeltä "hello". Käännös tapahtuu ylläkäsitellyillä  kääntäjillä
  236. seuraavasti: 
  237.  
  238. {3Aztec
  239.  
  240. (Jos joku käyttää Aztecia, voi ehkä osata tehdä järkevämminkin.)
  241.  
  242. Yleisesti: cc <lähde>.c
  243.            ln <lähde>.o -l<kohde>
  244.  
  245. Eli hello.c käännetään:
  246.  
  247. cc hello.c
  248. ln hello.o -lhello
  249.  
  250. {3DICE C
  251.  
  252. Yleisesti: dcc <lähde> -o <kohde>
  253.  
  254. Eli hello.c käännetään:
  255.  
  256. dcc hello.c -o hello
  257.  
  258. {3GCC
  259.  
  260. Yleisesti: gcc <lähde> -o <kohde>
  261.  
  262. Eli hello.c käännetään:
  263.  
  264. gcc hello.c -o hello
  265.  
  266. {3SAS/C
  267.  
  268. Yleisesti: sc <lähde> link to <kohde>
  269.  
  270. Eli hello.c käännetään:
  271.  
  272. sc hello.c link to hello
  273.  
  274. Kaikki kääntäjät osaavat paljon muutakin, joten kannattaa tutustua huolelli-
  275. sesti käyttämäänsä kääntäjään.
  276.  
  277. Jos käännös on onnistunut, pitäisi tuloksena olla ajettava tiedosto "hello".
  278. Kokeile ajaa se; sen pitäisi  tulostaa  "Hello  World!"  CLI/Shell-ikkunaan,
  279. josta se ajettiin.
  280.  
  281.  
  282. {3Välissä kehittyneempää tietoa kiinnostuneille
  283.  
  284. Yksi syy, miksi C-kieltä on virheellisesti pidetty tehottomana, on se,  että
  285. tällainenkin esimerkki tuottaa  varsin  suuren  ajettavan  tiedoston.  Tämän
  286. "hello":n koko käännettynä on kääntäjäkohtaisesti n. 2-5kB. Tästä  kuitenkin
  287. itse lähdekoodissa oleva osuus on enintään hieman yli 200 tavua,  vaihdellen
  288. kääntäjän ja käytettyjen optioiden mukaan. Kokonaisuuden suhteessa suuri ko-
  289. ko johtuu siitä, että ohjelman lopullisessa ajettavassa muodossa on  linkat-
  290. tuna mukaan kaksi alustuskooditasoa. (Linkkauksesta puhutaan myöhemmin kurs-
  291. sissa.) Niistä matalampitasoinen  yleensä  tallentaa  pino-osoittimen  arvon
  292. (jotta ohjelmasta voidaan poistua helpommin riippumatta  poistumiskohdasta),
  293. avaa dos.library-systeemikirjaston ja varautuu siihen, että ohjelma on käyn-
  294. nistetty Workbenchistä. Tämän jälkeen kutsutaan korkeamman tason alustuskoo-
  295. dia, joka valmistelee C:n stdio-tiedostot ja muotoilee komentorivillä  anne-
  296. tut parametrit C:n main():in käyttämään muotoon. Vasta kaiken tämän  jälkeen
  297. kutsutaan main():ia eli varsinaista käyttäjän tekemää ohjelmaa. Alustuskoodi
  298. itsessäänkään ei vie niin paljon tilaa, vaan ohjelmaan joudutaan linkkaamaan
  299. myös C:n tavallisia funktioita, hello.c:n tapauksessa ainakin seuraavia: fo-
  300. pen(), fclose(), fwrite(), write(), puts() ja malloc(). (GCC on tässä  poik-
  301. keus; osa näistä rutiineista on sijoitettu  ixemul.library-kirjastoon,  jol-
  302. loin niitä ei tarvitse sisällyttää jokaiseen ohjelmaan erikseen.)
  303.  
  304. Suuremmissa ohjelmissa koon kasvu linkatun informaation takia  ei  ole  niin
  305. merkittävää, koska niissä itse ohjelman  osuus  on  huomattavasti  suurempi.
  306. Pieniä ohjelmia tehdessään monet kuitenkin  haluavat  minimoida  ohjelmiensa
  307. koon jättämällä kaikki C:n alustukset pois. Tämä vaatii jonkinasteista  Ami-
  308. gan käyttöjärjestelmän tuntemusta, koska vain joitain harvoja yksinkertaisia
  309. (lähinnä merkkijonon manipulointiin käytettyjä) C:n standardifunktioita voi-
  310. daan kutsua. Tällä tavalla tehtynä esimerkisi hello.c voitaisiin tehdä  seu-
  311. raavasti: 
  312.  
  313. #include <exec/types.h>
  314. #include <exec/libraries.h>
  315. #include <dos/dos.h>
  316.  
  317. #ifdef __GNUC__
  318.  
  319. #include <inline/exec.h>
  320. #include <inline/dos.h>
  321.  
  322. int callstart(void)
  323. {{
  324.   return start();
  325. }
  326.  
  327. #else
  328.  
  329. #include <clib/exec_protos.h>
  330. #include <clib/dos_protos.h>
  331.  
  332. #include <proto/exec.h>
  333. #include <proto/dos.h>
  334.  
  335. #endif
  336.  
  337. int start(void)
  338. {{
  339.   struct Library *SysBase, *DOSBase;
  340.  
  341.   SysBase = *(struct Library **)4;
  342.   if (DOSBase = OpenLibrary("dos.library", 0)) {
  343.     Write(Output(), "Hello World!\n", 13);
  344.     CloseLibrary(DOSBase);
  345.   }
  346.   return 0;
  347. }
  348.  
  349. Tämän pitäisi kääntyä ainakin DICE:lla, SAS/C:llä ja GCC:llä, jos osaa aset-
  350. taa optiot oikein ja omistaa tarpeelliset includet. Tuloksena olevan ajetta-
  351. van ohjelman koon  pitäisi  olla  alle  130  tavua  DICE:lla  tai  SAS/C:llä
  352. käännettynä, GCC:llä tämän tyyppinen tekniikka toimii varsin huonosti.  Pal-
  353. joa tätä pienemmäksi ei vastaavaa ohjelmaa  saisi  assemblerillakaan.  Kokoa
  354. voisi hieman vähentää jättämällä pois rekisterien tallentaminen pinoon, joka
  355. poikkeuksellisesti ei ole tässä tarpeellista.
  356.  
  357.  
  358. {3C-kielen muotoilu
  359.  
  360. C-kieli on hyvin vapaamuotoista: siinä voi olla jokaisen  elementin  välissä
  361. rajoittamaton määrä "tyhjää" (tyhjäksi lasketaan välilyönnit, tabulaattorit,
  362. rivinvaihdot sekä kommentit). Ottakaamme  esimerkiksi  hello.c:ssä  käytetty
  363. funktion puts() kutsu: 
  364.  
  365. puts("Hello World!");
  366.  
  367. puts ( "Hello World!" ) ;
  368.  
  369. puts
  370.      (
  371.       "Hello World!"
  372.      )
  373.      ;
  374.  
  375.  
  376. Kaikki ylläolevat tarkoittavat  C-kääntäjän  näkökulmasta  samaa,  koska  ne
  377. koostuvat samoista viidestä elementistä: "puts", "(", "Hello World!", ")" ja
  378. ";".
  379.  
  380. Kuten useimmissa muissakin kielissä, myös C-kielessä voidaan ohjelman lähde-
  381. koodiin kirjoittaa kommentteja,  jotka  eivät  vaikuta  itse  ohjelmaan  mi-
  382. tenkään, koska kääntäjä ei huomioi niitä. C-kielen  kommentit  alkavat  mer-
  383. keillä "/*" ja loppuvat merkkeihin "*/" ja voivat sijaita lähes missä  vain.
  384. Yllä esimerkkinä käytetty tarkoittaisi edelleen samaa, vaikka  sen  kirjoit-
  385. taisi muotoon: 
  386.  
  387. puts /* this is a comment */ (
  388.   "Hello World!"
  389.   /*
  390.    * this is a block comment
  391.    */
  392.   );
  393.  
  394. Lisäksi monet C-kääntäjät hyväksyvät C++-tyylisiä kommentteja. Nämä  alkavat
  395. merkeillä  "//"  ja  jatkuvat  rivin  loppuun.  Edelleen  samaa   esimerkkiä
  396. käyttäen: 
  397.  
  398. puts ( // This is a C++ comment
  399.       "Hello World!");
  400.  
  401. Aivan erityinen "tyhjän" merkki on "\" rivin lopussa. Tällä  ilmaistaan  ri-
  402. vin jatkumista seuraavan rivin alusta, ja se voi vaikka jakaa jonkun normaa-
  403. listi yhtenäisen koodin osan muuttamatta sen merkitystä: 
  404.  
  405. pu\
  406. ts("Hello World!");
  407.  
  408. Rivin lopussa oleva "\" ei kuitenkaan yleensä  ole  tällaisissa  tilanteissa
  409. hyödyllinen. Käytännössä sitä käytetään yleisimmin esikäsittelijän ohjausko-
  410. mentojen yhteydessä. Ne ovat varsinaiseen C-koodiin nähden poikkeuksellisia,
  411. koska ne ovat aina rivin mittaisia. Näistä lisää myöhemmin.
  412.  
  413. Joillakin kääntäjillä voi myös kommenteilla hajottaa osia muuttamatta niiden
  414. merkitystä. Seuraava toimii useilla kääntäjillä:
  415.  
  416. pu/* */ts("Hello World!");
  417.  
  418. Tällainen saattaa myös toimia:
  419.  
  420. pu/*
  421.    */ts("Hello World!");
  422.  
  423. Näiden kommenttijakojen toimivuuteen ei kuitenkaan kannata luottaa.
  424.  
  425. Usein vaaditaan osien välille vähintään yksi tyhjä, jotta ne voidaan erottaa
  426. toisistaan, esimerkiksi hello.c:ssä on eräällä rivillä: 
  427.  
  428. int main(int ac, char **av)
  429.  
  430. Mahdollisimman paljon tiivistettynä tämä olisi: 
  431.  
  432. int main(int ac,char**av)
  433.  
  434. Tämän enempää ei voida tiivistää, koska "intmain" tai  "intac"  näyttäisivät
  435. yhdeltä "sanalta".
  436.  
  437. Vaikka C-kieltä voidaan muotoilla näin vapaasti, käytetään kuitenkin yleensä
  438. täysin säännönmukaista muotoilua ohjelman rakenteen selkeyden vuoksi. Mitään
  439. virallista  tapaa  ei  varsinaisesti  ole,  mutta  on   kuitenkin   "yleinen
  440. käytäntö", jota useimmat C-ohjelmoijat seuraavat. Tämä käytäntö  ei  kuiten-
  441. kaan ole kovinkaan tarkka, vaan aika yleinen, joten jotkut asiat vaihtelevat
  442. aina ohjelmoijan mukaan.
  443.  
  444. Yleiseen käytäntöön kuuluu, että jokainen ohjelman lohko ("{"- ja  "}"-merk-
  445. kien välissä oleva ohjelmaosuus) sisennetään. Kuitenkin sisennyksen määrä ja
  446. aaltosulkeiden sijoittelu vaihtelee. Yleensä sisennys on 2-4 merkkiä. Jotkut
  447. käyttävät 8 merkin sisennystä, mikä tosin vaikeuttaa ohjelman rakenteen hah-
  448. mottamista jo siinä määrin, että ohjelmoijan on vaikea hyödyntää C:n  raken-
  449. teellisuuden etuja, ja ohjelman tekninen toiminta kärsii (oma "teoria" -  ei
  450. ole pakko uskoa). Tässä pari esimerkkiä sisennyksestä ja aaltosulkeiden  si-
  451. joittelusta (typerä esimerkkifunktio, ei kokeiltavaksi  tai  ymmärrettäväksi
  452. tarkoitettu): 
  453.  
  454. /*
  455.  * yksinkertainen sijoittelu, 2 merkin sisennykset
  456.  */
  457.  
  458. void procedure(void)
  459. {{
  460.   int i, s;
  461.  
  462.   for (i = 10, s = 5; i; --i)
  463.   {
  464.     s += i * 3;
  465.     if (i == 5)
  466.     {
  467.       printf("at i = 5, s = %d\n", s);
  468.       i -= s / 10;
  469.     }
  470.     else
  471.     {
  472.       printf("loop iteration %d\n", i);
  473.       s = -s;
  474.     }
  475.   }
  476.   puts("done");
  477. }
  478.  
  479. /*
  480.  * hieman erikoisempi sijoittelu, 4 merkin sisennykset
  481.  */
  482.  
  483. void procedure(void)
  484. {{
  485.     int i, s;
  486.  
  487.     for (i = 10, s = 5; i; --i)
  488.       {
  489.         s += i * 3;
  490.         if (i == 5)
  491.           {
  492.             printf("at i = 5, s = %d\n", s);
  493.             i -= s / 10;
  494.           }
  495.         else
  496.           {
  497.             printf("loop iteration %d\n", i);
  498.             s = -s;
  499.           }
  500.       }
  501.     puts("done");
  502. }
  503.  
  504. /*
  505.  * tiiviimpi sijoittelu, 2 merkin sisennykset
  506.  * (tässä kurssissa käytetty muoto)
  507.  */
  508.  
  509. void procedure(void)
  510. {{
  511.   int i, s;
  512.  
  513.   for (i = 10, s = 5; i; --i) {
  514.     s += i * 3;
  515.     if (i == 5) {
  516.       printf("at i = 5, s = %d\n", s);
  517.       i -= s / 10;
  518.     } else {
  519.       printf("loop iteration %d\n", i);
  520.       s = -s;
  521.     }
  522.   }
  523.   puts("done");
  524. }
  525.  
  526. Ylläolevissa esimerkeissä  tulee  esille  myös  muita  muotoiluun  liittyviä
  527. asioita, kuten välien käyttö. Kun kutsutaan/määritellään  funktioita  (tässä
  528. niitä ovat "procedure", "printf" ja "puts"), ei yleensä laiteta  väliä  sul-
  529. keiden ympärille eikä sisäpuolelle. (Tosin jotkut - aika harvat -  käyttävät
  530. väliä rutiinin nimen ja "("-merkin välissä.) Kun taas käytetään  C:n  raken-
  531. teita (tässä: "for", "if"; muita: "while", "switch"), laitetaan yleensä sul-
  532. keiden  ympärille  välit  (jälleen  kerran  poikkeuksia  löytyy).  Sulkeiden
  533. sisäpuolella harvat käyttävät missään yhteydessä välejä.
  534.  
  535. Pilkun jälkeen tulee aina väli, ennen pilkkua ei. (Tosin tämäkin  voi  vaih-
  536. della pilkkun käyttöpaikan mukaan.)
  537.  
  538. Lausekkeissa yleensä käytetään välejä eri operaattoreiden ("=",  "==",  "+",
  539. "-" jne.) molemmin puolin, poikkeuksena esimerkiksi "-" silloin, kun se tar-
  540. koittaa negatiivista arvoa eikä vähennyslaskua.
  541.  
  542. Kommentit sijoitetaan yleensä rivin  loppuun  tai  tyhjälle  riville.  Usein
  543. tyhjälle riville laitettu kommentti  kannattaa  laittaa  useammalle  riville
  544. esimerkkien selostuksissa näkyvään tyyliin.
  545.  
  546. Enemmänkin "käytäntöjä" on, mutta ne käyvät ilmi myöhemmin itse kielen opet-
  547. telun yhteydessä.
  548.  
  549. Jos joutuu lukemaan paljon toisten kirjoittamaa  C-koodia  ja  on  muotoilun
  550. suhteen yhtä neuroottinen kuin minä, kannattaa etsiä käsiinsä "indent"-  oh-
  551. jelma, joka automaattisesti muotoilee C-sorsia  sille  annettujen  optioiden
  552. mukaisesti. 
  553.  
  554.  
  555. {3Funktiot
  556.  
  557. C-kielisen ohjelman eräitä oleellisia osia ovat  funktiot  (tai  "rutiinit",
  558. englanniksi "functions" tai "procedures"). Funktioita voidaan määritellä  ja
  559. kutsua. Esimerkkiohjelma hello.c määritteli funktion main() ja kutsui  funk-
  560. tiota puts(): 
  561.  
  562. int main(int ac, char **av) /* funktion esittely                 */
  563. {{                           /* funktion koodin määrittely alkaa  */
  564.   puts("Hello World!");     /* kutsutaan funktiota puts()        */
  565.   return 0;                 /* palautetaan 0                     */
  566. }                           /* funktion koodin määrittely loppuu */
  567.  
  568. Funktion esittely määrittelee funktion nimen, minkätyyppisen  arvon  funktio
  569. palauttaa sekä minkätyyppiset parametrit sillä on (tyypeistä  tarkemmat  se-
  570. lostukset myöhemmin). Esimerkissä funktion nimi on main, se palauttaa arvon,
  571. jonka tyyppi on int (eräs kokonaislukutyyppi), parametrien tyypit  ovat  int
  572. ja char **, joille annetaan muuttujanimikkeet ac  ja  av  funktion  sisällön
  573. ajaksi, eli ne ovat käytettävissä kuten mitkä tahansa paikalliset  muuttujat
  574. (muuttujistakin lisää tietoa myöhemmin).
  575.  
  576. Funktion esittelyn muuttujien määrittelylle on myös toinen  tapa.  Ylläoleva
  577. ja  tässä  kurssissa  yleensä  käytetty  on  ANSI:n  mukainen  tapa.  Jotkut
  578. käyttävät vanhaa K&R tyyliä: 
  579.  
  580. int main(ac, av)
  581.   int ac;
  582.   char **av;
  583. {{
  584.   puts("Hello World!");
  585.   return 0;
  586. }
  587.  
  588. Funktiolla main() on erityinen merkitys, sillä  C-ohjelman  suoritus  kutsuu
  589. sitä automaattisesti. Tämän takia ovat main():in parametrien ja  palautuksen
  590. tyypit aina samat, vaikka ohjelma ei käyttäisikään parametreja mihinkään.
  591.  
  592. Funktion varsinainen sisältö tulee esittelyn jälkeen aaltosulkeiden välissä.
  593. Funktion sisältö määrää, mitä funktio tekee, kun sitä kutsutaan.
  594.  
  595. Kun funktiosta poistutaan, se voi palauttaa jonkin arvon. Funktiomme  main()
  596. palauttaa arvon, joka on tyypiltään int, kuten on määritelty funktion  esit-
  597. telyssä. Arvo palautetaan komennolla  (yksi  C-kielen  kahdesta  komennosta)
  598. "return", jolla asetetaan palautusarvo ja poistutaan  funktiosta.  hello.c:n
  599. tapauksessa on palautusarvona luku 0. Mitään return:in jälkeisiä  toimintoja
  600. funktiossa ei suoriteta, jos muuttaisimme järjestystä hello.c:ssä: 
  601.  
  602. int main(int ac, char **av)
  603. {{
  604.   return 0;
  605.   puts("Hello World!"); /* ei koskaan suoriteta */
  606. }
  607.  
  608. Tässä ei ohjelman suoritus edes pääsisi puts():in kutsuun, koska  funktiosta
  609. on poistuttu jo ennen sitä.
  610.  
  611. Komentoa "return" voidaan käyttää myös ilman palautusarvoa, jos  funktio  on
  612. määritelty sellaiseksi, joka ei palauta mitään (eli esittelyssä on palautus-
  613. tyypiksi määritelty pseudo-tyyppi "void"). Tyyppiä  "void"  voidaan  käyttää
  614. myös ilmaisemaan, ettei funktiolle anneta parametreja. 
  615.  
  616. /*
  617.  * funktio, joka ei ota parametreja eikä palauta mitään
  618.  */
  619.  
  620. void func1(void)
  621. {{
  622.   return;
  623. }
  624.  
  625. /*
  626.  * kun funktio ei palauta mitään, voidaan return-komento jättää pois,
  627.  * sillä funktiosta poistutaan automaattisesti myös kun funktio loppuu
  628.  */
  629.  
  630. void func2(void)
  631. {{
  632. }
  633.  
  634. Seuraavaksi esimerkkiohjelma, joka demonstroi sellaisen funktion kutsumista,
  635. joka ei ota parametreja:
  636.  
  637. #include <stdio.h>
  638.  
  639. void test(void)
  640. {{
  641.   puts("testing...");
  642. }
  643.  
  644. int main(int ac, char **av)
  645. {{
  646.   test();
  647.   puts("ok");
  648.   return 0;
  649. }
  650.  
  651. Tämän esimerkin pitäisi tulostaa shell-ikkunaan:
  652.  
  653. testing...
  654. ok
  655.  
  656. Tässä funktion test() voisi määritellä vanhaan tyyliin ilman "void":ia para-
  657. metrien korvikkeena:
  658.  
  659. void test()
  660. {{
  661.   puts("testing...");
  662. }
  663.  
  664. Funktioiden määrittelemistä ja  kutsumista  käsitellään  myöhemmin  enemmän.
  665. Aluksi on kuitenkin syytä perehtyä hieman tarkemmin  tyyppeihin  ja  muuttu-
  666. jiin. 
  667.  
  668.  
  669. {3Muuttujat ja tyypit alustavasti
  670.  
  671. C-kielessä on muuttujille määriteltävissä useita eri tyyppejä. Perustyyppejä
  672. on tehokas käsitellä, koska ne ovat samoja tyyppejä, joita koneen prosessori
  673. osaa käsitellä suoraan.
  674.  
  675. Ennen tyyppien selitystä ja muuta kurssissa tulevaa on syytä käsitellä  joi-
  676. takin tietokoneiden toimintaan liittyviä peruskäsitteitä, jotka lienevät mo-
  677. nille jo ennestään tuttuja:
  678.  
  679. Bitti (englanniksi "bit"): Nykyisten tietokoneiden toiminta pohjautuu  digi-
  680. taalisiin signaaleihin (vastakohtana  olisivat  esimerkiksi  stereolaitteet,
  681. joissa käytetään analogisia signaaleita), joilla on vain  kaksi  mahdollista
  682. tilaa. Näistä tiloista käytetään numeerisia ilmaisuja 0  ja  1.  Käytännössä
  683. nämä signaalit liikkuvat sähkönä johtimia pitkin, ja  numeerisia  merkintöjä
  684. vastaavat yleensä jännitteet 0V (eli 0) ja +5V (eli 1). Tietoa käsiteltäessä
  685. tällaisesta yksittäisestä signaalista (ja samalla tiedon pienimmästä mahdol-
  686. lisesta yksiköstä) käytetään nimitystä bitti.
  687.  
  688. Tavu (englanniksi "byte"): Koska bitillä voi ilmaista vain lukuja  0  ja  1,
  689. yhdistetään yleensä useampia bittejä, jotka yhdessä voivat esittää hyödylli-
  690. sempiä lukuja (käytännössä tämä tehdään rinnakkaisilla johtimilla).  Yleensä
  691. pienin tällä tavalla käsitelty tiedon yksikkö on tavu,  eli  8  rinnakkaista
  692. bittiä. Tavun bitit numeroidaan nollasta seitsemään. Tavun  arvo  on  päällä
  693. (eli tilassa 1) olevien bittien arvojen summa. Bitin arvo on  2^n  (jossa  ^
  694. tarkoittaa potenssiin korotusta ja n on bitin numero).  Bitti  numero  7  on
  695. siis tavun eniten merkitsevä, ja bitti numero 0  vähiten  merkitsevä  bitti.
  696. Kun tavun arvo kirjoitetaan binäärimuotoon  (2-kantainen  luku),  aloitetaan
  697. eniten merkitsevästä bitistä.
  698.  
  699. Heksadesimaalinotaatio: Koska 10-kantaiset luvut eivät sovellu  kovin  hyvin
  700. tietokoneissa käytettäviksi (ne eivät mene bitteinä tasan), käytetään moniin
  701. tarkoituksiin 16-järjestelmää (heksadesimaalilukuja), jossa käytetään  nume-
  702. roiden 0-9 lisäksi kirjaimia a-f lukujen kirjoittamiseen.  Heksadesimaalilu-
  703. vun tunnuksena on C-kielessä 0x (assemblerissa se on  $).  Heksadesimaalilu-
  704. vuissa on se etu, että jokainen numero vastaa suoraan neljää bittiä, eli ta-
  705. vun arvo on aina ilmaistavissa kahdella heksanumerolla. Tavun arvo  on  siis
  706. väliltä 0x00 (desimaalina 0) - 0xff (desimaalina 255).
  707.  
  708. Muisti: Tiedon ilmaisemisesta hetkellisinä signaaleina ei  ole  sellaisenaan
  709. mitään hyötyä, vaan tietoa täytyy voida  säilyttää  jotenkin.  Tieto  säily-
  710. tetään muistin avulla, joka on periaatteessa vain alue  peräkkäisiä  tavuja.
  711. Yleisimmin muistina käsitetty muisti on RAM-muistia  ("Random  Access  Memo-
  712. ry"), johon voidaan kirjoittaa ja josta voidaan lukea. Amigassa  dos-komento
  713. "avail" kertoo vapaana olevan RAM-muistin määrän, miten  paljon  sitä  enim-
  714. millään voisi olla ja miten paljon sitä on käytössä. (Amigassa RAM-muisti on
  715. edelleen jaoteltu kahdentyyppiseen muistiin: chip-muisti, joka on  keskusyk-
  716. sikön lisäksi kaikkien erikoisprosessoreiden osoitettavissa ja  fast-muisti,
  717. joka on nopeampaa, koska keskusyksikkö saa sillä enemmän väyläaikaa.)  Muis-
  718. tin suhteen ei sinänsä ole olemassa  käsitteitä  "vapaana"  tai  "käytössä",
  719. vaan Amigan käyttöjärjestelmä (kuten  useimmat  muutkin  käyttöjärjestelmät)
  720. pitää  lukua  RAM-muistin  käytöstä.  Muistin  "määrä"  lasketaan  tavuissa.
  721. Lisäksi on ROM-muistia ("Read Only Memory"), jota voi vain  lukea.  Amigassa
  722. keskeisimmät osat käyttöjärjestelmästä ovat ROM-muistissa. (Juuri  tästä  on
  723. kyse, kun puhutaan "Kickstart ROM":ista.)
  724.  
  725. Muistiosoite: Muistia käsiteltäessä on  kyettävä  ilmaisemaan,  mitä  kohtaa
  726. muistissa halutaan käsitellä. Tämän takia muisti on kartoitettu osoitteiksi.
  727. Periaatteessa muistiosoite ilmoittaa vain, monesko tavu muistia on kyseessä,
  728. tosin kaikissa osoitteissa ei välttämättä ole muistia. Motorolan  680x0-sar-
  729. jan prosessoreissa (joita Amigassa käytetään) muistiosoitteet ovat 32-bitti-
  730. siä lukuja (tosin 68000/68010 huomioivat vain vähiten  merkitsevät  24  bit-
  731. tiä), eli neljän tavun mittaisia. Muistiosoitteet voivat siis  periaatteessa
  732. olla väliltä 0 - 0xffffffff (desimaalina 4294967295 - hyvä esimerkki  siitä,
  733. miksi heksadesimaaliluvut ovat käytännöllisiä). Amigan  RAM-muistista  chip-
  734. muisti alkaa yleensä osoitteesta 0 ja jatkuu enintään osoitteeseen  0x1fffff
  735. (jos on 2MB chip-muistia). 16-bittinen fast-muisti  (60000/68010-pohjaisissa
  736. koneissa oleva fast-muisti) sijaitsee osoitteesta 0x200000  alkaen  enintään
  737. 8MB  eteenpäin.  32-bittinen  fast-muisti  (jonka  osoittamiseen   tarvitaan
  738. vähintään 68020) alkaa osoitteesta 0x7800000. Amigan Kickstart ROM sijaitsee
  739. joko osoitteesta 0xf80000 (2.0 ja uudemmat versiot) tai  0xfc0000  osoittee-
  740. seen 0xffffff. Näiden muistityyppien  lisäksi  on  Amigassa  sekä  kiinteitä
  741. pseudomuistipaikkoja, joiden avulla ohjataan erikoisprosessoreita (osoitteet
  742. 0xdff???) ja CIA-piirejä (osoitteet 0xbfe?01 ja 0xbfd?00),  että  oheislait-
  743. teiden ohjausosoitteita.
  744.  
  745. Pino (englanniksi "stack"): Jokaisella käynnissä olevalla ohjelmalla on alue
  746. muistia, jota kutsutaan pinoksi. Amigassa käynnistettävien  ohjelmien  pinon
  747. kokoa voi muuttaa shellistä stack-komennolla ja Workbenchistä ohjelman  iko-
  748. nin tiedoilla. Pinoa käytetään esimerkiksi  ohjelman  kutsuessa  aliohjelmia
  749. (C:ssä funktiokutsut) paluuosoitteen säilyttämiseen. Pino toimii pino-osoit-
  750. timella, joka asetetaan aluksi osoittamaan muistialueen  loppuun.  Aina  kun
  751. pinoon tallennetaan jotain, vähennetään ensin pino-osoittimesta tallennetta-
  752. van olion koko, ja  sitten  asetetaan  pino-osoittimen  osoittamaan  kohtaan
  753. olion sisältö. Pino-osoitin osoittaa siis aina viimeksi  pinoon  tallennetun
  754. olion alkuun. Kun  pinosta  otetaan  jotain  pois,  otetaan  pino-osoittimen
  755. osoittamasta kohdasta olion arvo ja lisätään pino-osoittimeen sen koko.  Pi-
  756. nosta on siis aina otettava pois kaikki, mitä sinne laitetaan päinvastaises-
  757. sa järjestyksessä kuin missä ne on laitettu sinne. C-kielellä ohjelmoitaessa
  758. ei tarvitse sen enempää välittää pinon toiminnasta, mutta koska Amigalla  on
  759. ohjelmilla tavallisesti kiinteät pinot, kannattaa välttää  käyttämästä  run-
  760. saasti pino-muistia vaativaa ohjelmointitekniikkaa.
  761.  
  762. C-kielen yksinkertaisimpia tyyppejä ovat kokonaisluvut.  Näitäkin  on  usean
  763. tyyppisiä (erikokoisia, etumerkillisiä ja etumerkittömiä). Tässä ovat  tyyp-
  764. pien koot lueteltuna sellaisina kuin ne ovat  yleisimmin  Amigalla.  Jos  ei
  765. tiedä, minkä kokoisina kääntäjässä on toteutettu nämä, kannattaa katsoa inc-
  766. lude-tiedostosta "limits.h" (include-tiedostoista lisää myöhemmin). 
  767.  
  768.   char
  769.   signed char
  770.  
  771. "char" on tavun mittainen eli 8-bittinen kokonaisluku. Arvo voi olla -128  -
  772. 127. Tätä tyyppiä käytetään usein tekstin yhteydessä, koska  ASCII-tekstissä
  773. jokainen merkki on yksi tavu.
  774.  
  775. Tämä tyyppi on etumerkillinen, eli jos eniten merkitsevä  bitti  on  päällä,
  776. ilmaisee se luvun olevan negatiivinen. Negatiivinen arvo lasketaan vastaava-
  777. na positiivisena arvona vähennettynä nollasta, eli suurin negatiivinen  luku
  778. (-1) on 0xff, pienin negatiivinen luku (-128) on 0x80.
  779.  
  780. Joissain kääntäjissä on optio, jota käytettäessä "char" tarkoittaa "unsigned
  781. char":ia, ja etumerkillistä tavua varten täytyy käyttää "signed char":ia. 
  782.  
  783.   unsigned char
  784.  
  785. Kuten char, mutta etumerkitön. Arvo voi olla 0 - 255 (0x00 - 0xff).
  786.  
  787.   short
  788.   signed short
  789.   short int
  790.   signed short int
  791.  
  792. "short" on etumerkillinen, 16-bittinen (kahden tavun mittainen)  kokonaislu-
  793. ku. 680x0-prosessoreilla short tallennetaan  muistiin  kahteen  peräkkäiseen
  794. tavuun,  eniten  merkitsevä  tavu  ensin  (pienemmässä   muistiosoitteessa).
  795. 68000/68010:llä on shortin oltava parillisessa osoitteessa  (shortin  osoite
  796. on sen ensimmäisen tavun osoite). Arvo voi olla -32768 - 32767. 
  797.  
  798.   unsigned short
  799.   unsigned short int
  800.  
  801. Kuten short, mutta etumerkitön. Arvo voi olla 0 - 65535 (0x0000 - 0xffff).
  802.  
  803.   int
  804.   signed int
  805.  
  806. "int" on yleensä samanlainen kuin "long". Joissain kääntäjissä se  voi  olla
  807. joko optiolla tai aina (Aztec) kuten "short". 
  808.  
  809.   unsigned int
  810.  
  811. Kuten int, mutta etumerkitön.
  812.  
  813.   long
  814.   signed long
  815.   long int
  816.   signed long int
  817.  
  818. "Long" on etumerkillinen, 32-bittinen (neljän tavun mittainen) kokonaisluku.
  819. 680x0-prosessoreilla long tallennetaan muistiin neljään peräkkäiseen tavuun,
  820. eniten merkitsevä tavu ensin. 68000/68010:llä on longin oltava  parillisessa
  821. osoitteessa. Arvo voi olla -2147483648 - 2147383647. 
  822.  
  823.   unsigned long
  824.   unsigned long int
  825.  
  826. Kuten long, mutta etumerkitön. Arvo voi olla 0 -  4294967295  (0x00000000  -
  827. 0xffffffff).
  828.  
  829.   long long 
  830.   signed long long
  831.   long long int
  832.   signed long long int
  833.  
  834. Joissain kääntäjissä (ainakin GCC:ssä) on  käytettävissä  64-bittinen  koko-
  835. naislukutyyppi. 680x0-prosessorit eivät suoraan tue 64-bittisiä lukuja,  jo-
  836. ten näiden käsittely on hieman monimutkaisempaa ja hitaampaa kuin muiden ko-
  837. konaislukutyyppien. Etumerkillisen, 64-bittisen kokonaisluvun arvo voi  olla
  838. -9223372036854775808 - 9223372036854775807. 
  839.  
  840.   unsigned long long
  841.   unsigned long long int
  842.  
  843. Kuten long long, mutta etumerkitön. Arvo voi olla  0 -  18446744073709551615
  844. (0x0000000000000000 - 0xffffffffffffffff).
  845.  
  846.  
  847. {3Muuttujan määrittely
  848.  
  849. Muuttujaa määriteltäessä on muuttujalle  annettava  jokin  tyyppi  ja  nimi.
  850. Tyyppi voi olla esimerkiksi jokin ylläolevista kokonaislukutyypeistä.  Muut-
  851. tujan nimi voi olla periaatteessa minkä pituinen vain (tosin  jotkut  vanha-
  852. naikaiset kääntäjät tunnistavat muuttujan vain nimen  ensimmäisen  kahdeksan
  853. merkin perusteella - ANSIn mukaan tarvitsee huomioida vähintään  ensimmäiset
  854. 31 merkkiä) ja voi sisältää kirjaimia a-z (sekä isoja että pieniä), numeroi-
  855. ta sekä "_"-merkkejä. Muuttujan nimen ensimmäinen merkki ei saa olla numero.
  856. Isot kirjaimet ja pienet kirjaimet eivät vastaa  toisiaan,  joten  voi  olla
  857. esimerkiksi muuttuja nimeltä A ja muuttuja nimeltä a ilman, että ne  sekoit-
  858. tuvat keskenään.
  859.  
  860. Muuttujan nimeksi ei voi antaa mitään C-kielen kannalta  jotain  merkitseviä
  861. avainsanoja (kuten tyyppien nimiä).
  862.  
  863. Esimerkkejä muuttujien määrittelystä: 
  864.  
  865. /*
  866.  * määritellään muuttuja alpha tyyppiä long:
  867.  */
  868.  
  869. long alpha;
  870.  
  871. /*
  872.  * muuttujia voidaan määritellä myös useampia kerralla:
  873.  *
  874.  * määritellään muuttujat a, b ja c, tyyppiä short:
  875.  */
  876.  
  877. short a, b, c;
  878.  
  879. /*
  880.  * joka on sama asia kuin:
  881.  */
  882.  
  883. short a;
  884. short b;
  885. short c;
  886.  
  887. /*
  888.  * määritellään muuttuja mychr tyyppiä unsigned char:
  889.  */
  890.  
  891. unsigned char mychr;
  892.  
  893. Usein muuttujia nimetessä kannattaa käyttää nimitystä, joka  kuvaa  (yleensä
  894. lyhennettynä englanninkielestä) jotenkin muuttujan tehtävää.  Jos  muuttujaa
  895. käytetään vain hetkellisesti, eikä sille löydy mitään  loogista  lyhennettä,
  896. nimetään muuttuja usein yhdellä tai  kahdella  kirjaimella.  Muuttujien  ni-
  897. meäminen esim. suomeksi tai sanoin, jotka eivät liity mitenkään  asiaan,  on
  898. kaikkea muuta kuin suositeltavaa.
  899.  
  900. Muuttujaa voidaan määrittelyn jälkeen käyttää ohjelman siinä  lohkossa  (eli
  901. aaltosulkeiden välissä olevassa osassa), jossa muuttuja on  määritelty.  Jos
  902. muuttujan  määrittely  ei  ole  minkään  funktion   sisällä,   on   muuttuja
  903. käytettävissä kaikissa funktioissa koko loppuohjelmassa, eli se on  "globaa-
  904. li" muuttuja. Muulloin on kyseessä paikallinen muuttuja.
  905.  
  906. Funktion parametreissa nimetty muuttuja on käytettävissä aina kyseisen funk-
  907. tion sisällä.
  908.  
  909. Muuttuja vaatii tietysti paikan, jossa sitä voi säilyttää. Säilytystilaa  se
  910. tarvitsee tyyppinsä koon  verran.  Periaatteessa  C-kääntäjä  saa  säilyttää
  911. muuttujia miten haluaa, mutta ainakin Amigalla tuntuvat kaikki kääntäjät te-
  912. kevän sen suunnilleen samoin. Globaalit muuttujat sijoitetaan  ohjelman  da-
  913. ta/bss-hunkkeihin, jotka ovat ohjelman ajon ajan kiinteästi muistissa olevia
  914. alueita. Paikallisista muuttujista osa sijoitetaan keskusyksikön rekisterei-
  915. hin (yleensä eniten käytetyt) ja  osalle  varataan  tilaa  pinosta  kyseisen
  916. funktion suorituksen ajaksi.
  917.  
  918.  
  919. {3Lauseet ja lausekkeet
  920.  
  921. C-kielinen ohjelma  koostuu  useimmiten  pääasiassa  lauseista  (englanniksi
  922. "statements"), jotka ovat funktion sisällön toiminnallisia osia. Tyhjä lause
  923. olisi pelkkä ";"-merkki. Lauseet ovat usein joitakin rakenteita (if,  while,
  924. for, switch jne.) tai komentoja (return, goto). Lause voi myös olla  lauseke
  925. (englanniksi "expression"), jonka perässä on ";"-merkki. Myös komentolausei-
  926. den perässä on ";"-merkki. Lauseke koostuu puolestaan  yleensä  yhdestä  tai
  927. useammasta lausekkeesta, joiden välissä tai yhteydessä on operaatioita.  Pe-
  928. ruslausekkeita (eivät koostu useammasta lausekkeesta operaattoreilla  yhdis-
  929. tettynä) ovat esimerkiksi muuttujat, vakiot ja  funktiokutsut.  Lausekkeella
  930. on lähes poikkeuksetta arvo, mutta lauseke ei välttämättä tee mitään. Yksin-
  931. kertainen esimerkki lausekkeen muodostamasta lauseesta, joka ei tee mitään: 
  932.  
  933. 0;
  934.  
  935. Tässä on kyseessä perustyyppiä oleva lauseke, vakio. Lausekkeen arvo on  va-
  936. kion arvo, eli 0.
  937.  
  938. Hieman hyödyllisempi esimerkki lausekkeesta voisi olla arvon antaminen muut-
  939. tujalle. Tämä tehdään "="-operaattorilla. Esimerkiksi jos meillä on muuttuja
  940. "a", joka on jotain kokonaislukutyyppiä, voimme antaa sille arvon 0  seuraa-
  941. valla tavalla:
  942.  
  943. a = 0;
  944.  
  945. Operaattori "=" toimii siten, että sen molemmilla  puolilla  on  operandeina
  946. lausekkeet. Myös tämä kokonaisuus on lauseke, joten jos meillä on  muuttujat
  947. a ja b (jotka ovat jossain määrin yhteensopivan tyyppisiä):
  948.  
  949. b = a = 0;
  950.  
  951. Tämä antaa siis ensin muuttujalle a arvon nolla, sitten antaa muuttujalle  b
  952. lausekkeen (a = 0) arvon, joka on myös 0. (Peräkkäiset "="-operaatiot suori-
  953. tetaan aina oikealta vasemmalle.) Tämä on siis sama kuin:
  954.  
  955. a = 0;
  956. b = a;
  957.  
  958. Operaattorin "=" vasemmalla puolella olevalla operandilla on sellainen  vaa-
  959. timus, että sen on oltava muutettavissa. (Englanniksi tällaisen  vaatimuksen
  960. täyttävää lauseketta kutsutaan nimellä  "modifiable  lvalue".)  Toistaiseksi
  961. kurssissa on käsitelty vasta yksi mahdollinen  lauseketyyppi,  joka  täyttää
  962. tämän vaatimuksen, eli muuttuja.
  963.  
  964. Lausekkeita voivat olla myös yksinkertaiset matemaattiset  laskutoimitukset;
  965. normaali laskujärjestys pätee ja sulkeita voidaan käyttää sen muuttamiseen:
  966.  
  967. int a, b, c; 
  968.  
  969. a = 1 + 5 * 8;   /* a:n arvoksi tulee 41  */
  970. b = 10 / 4 - a;  /* b:n arvoksi tulee -39 */
  971. c = 2 * (a + b); /* c:n arvoksi tulee 4   */
  972.  
  973. Muita laskennallisia operaattoreita ovat:
  974.  
  975.         %  jakojäännös
  976.  
  977. Käyttö esimerkiksi:
  978.  
  979. a = 5 % 3; /* a:n arvoksi tulee 2 */
  980.  
  981.  
  982.         &  "ja"-binäärioperaattori
  983.  
  984. Tuloksessa ovat tilassa 1 vain ne bitit, jotka olivat molemmissa operandeis-
  985. sa päällä, binäärilukuina esimerkiksi:
  986.  
  987.   0111001011010110 (heksana 0x72d6)
  988. & 1010100110101101 (heksana 0xa9ad)
  989. antaa tulokseksi:
  990.   0010000010000100 (heksana 0x2084)
  991.  
  992. Käyttö esimerkiksi:
  993.  
  994. a = 0xf0f0 & 0x5555; /* a:n arvoksi tulee 0x5050 */
  995.  
  996. /*
  997.  * sama desimaaliluvuilla (vaikeampi hahmottaa):
  998.  */
  999.  
  1000. a = 61680 & 21845; /* a:n arvoksi tulee 20560 */
  1001.  
  1002.  
  1003.         |  "tai"-binäärioperaattori
  1004.  
  1005. Tuloksessa ovat kaikki ne bitit ykkösiä, jotka olivat jommassakummassa  ope-
  1006. randissa päällä, binäärinä esim.:
  1007.  
  1008.   01001101 (heksana 0x4d)
  1009. | 11010110 (heksana 0xd6)
  1010. antaa tulokseksi:
  1011.   11011111 (heksana 0xdf)
  1012.  
  1013. Käyttö esimerkiksi:
  1014.  
  1015. a = 0x1111 | 0x3232; /* a:n arvoksi tulee 0x3333 */
  1016.  
  1017. /*
  1018.  * sama desimaaliluvuilla:
  1019.  */
  1020.  
  1021. a = 4369 | 12850; /* a:n arvoksi tulee 13107 */
  1022.  
  1023.  
  1024.         ^  "ehdoton tai"-binäärioperaattori
  1025.  
  1026. Tuloksessa ovat kaikki ne bitit ykkösiä, jotka olivat jommassakummassa  ope-
  1027. randissa mutta eivät molemmissa päällä, binäärinä esim.:
  1028.  
  1029.   10110100 (heksana 0xb4)
  1030. ^ 11011001 (heksana 0xd9)
  1031. antaa tulokseksi:
  1032.   01101101 (heksana 0x6d)
  1033.  
  1034.   Käyttö esimerkiksi:
  1035.  
  1036. a = 0x1f42 ^ 0x3729; /* a:n arvoksi tulee 0x286b */
  1037.  
  1038. /*
  1039.  * sama desimaaliluvuilla:
  1040.  */
  1041.  
  1042. a = 8002 ^ 14121; /* a:n arvoksi tulee 10347 */
  1043.  
  1044.  
  1045.         ~  "ei"-binäärioperaattori
  1046.  
  1047. Tämä on edeltämäänsä lausekkeeseen liittyvä operaattori (englanniksi  "unary
  1048. operator").
  1049.  
  1050. Tuloksen bitit ovat päinvastaisessa tilassa kuin operandin bitit,  binäärinä
  1051. esim.:
  1052.  
  1053. ~ 01100101 (heksana 0x65)
  1054. antaa tulokseksi:
  1055.   10011010 (heksana 0x9a)
  1056.  
  1057. Käyttö esimerkiksi:
  1058.  
  1059. a = ~0x4e82; /* a:n arvoksi tulee 0xb17d */
  1060.  
  1061. /*
  1062.  * sama desimaaliluvuilla:
  1063.  */
  1064.  
  1065. a = ~20098; /* a:n arvoksi tulee 45437 */
  1066.  
  1067.  
  1068.         <<  bittien siirto vasemmalle
  1069.  
  1070. Antaa tulokseksi vasemman operandin bitit siirrettynä vasemmalle oikean ope-
  1071. randin verran. Ellei laskussa tapahdu ylivuotoa, niin a << b on sama kuin  a
  1072. kerrottaisiin 2^b:llä (jossa ^ esittää potenssiin korotusta). 
  1073.  
  1074. a = 1 << 2; /* a:n arvoksi tulee 4 */
  1075.  
  1076.  
  1077.         >>  bittien siirto oikealle
  1078.  
  1079. Antaa tulokseksi vasemman operandin bitit siirrettynä oikealle  oikean  ope-
  1080. randin verran. Jos oikea operandi ei ole negatiivinen, niin a >> b  on  sama
  1081. kuin a jaettaisiin 2^b:llä (jossa ^ esittää potenssiin korotusta). 
  1082.  
  1083. a = 12 >> 1; /* a:n arvoksi tulee 6 */
  1084.  
  1085.  
  1086. {3Vertailuoperaattorit, if-rakenne
  1087.  
  1088. Lausekkeissa käytetään myös sellaisia operaatioita,  joilla  on  vain  kaksi
  1089. mahdollista arvoa: tosi tai epätosi. Tosi tarkoittaa mitä tahansa arvoa, jo-
  1090. ka ei ole nolla. Nolla on ainoa epätosi. Näitä operaatioita on kahdentyyppi-
  1091. siä: vertailulliset ja loogiset operaatiot.  Vertailuoperaattorit  vertaavat
  1092. molemmin puolin olevien lausekkeiden arvoja. Niitä ovat seuraavat:
  1093.  
  1094.  ==  samanarvoinen
  1095.  !=  eriarvoinen
  1096.  <   pienempi
  1097.  >   suurempi
  1098.  <=  pienempi tai sama
  1099.  >=  suurempi tai sama
  1100.  
  1101. Näitä voidaan käyttää tähän asti esitettyyn tyyliin, eli esimerkiksi:
  1102.  
  1103. a = b == 10;
  1104.  
  1105. (Asettaa muuttujan a 1:ksi jos muuttujan b arvo on  10,  muussa  tapauksessa
  1106. nollaa a:n).
  1107.  
  1108. Tai jopa:
  1109.  
  1110. a >= b;
  1111.  
  1112. (Ei tee mitään, koska tulosta ei käytetä mihinkään.)
  1113.  
  1114. Tämä ei kuitenkaan ole  kovin  hyödyllistä.  Vertailuoperaatioita  käytetään
  1115. yleensä silmukoiden (myöhemmin) ja if-rakenteiden yhteydessä:
  1116.  
  1117. if (<lauseke>) {
  1118.   /* ohjelman osa, joka suoritetaan vain jos <lauseke> on tosi */
  1119. }
  1120. /* ohjelma jatkuu */
  1121.  
  1122. tai:
  1123.  
  1124. if (<lauseke>) {
  1125.   /* ohjelman osa, joka suoritetaan vain jos <lauseke> on tosi */
  1126. } else {
  1127.   /* ohjelman osa, joka suoritetaan jos <lauseke> on epätosi */
  1128. }
  1129. /* ohjelma jatkuu */
  1130.  
  1131. Jos "if ()" - tai "else"-kohdan jälkeen tuleva ohjelman osa  muodostuu  vain
  1132. yhdestä lauseesta, voidaan aaltosulkeet jättää pois.
  1133.  
  1134. Esimerkkejä if-rakenteesta:
  1135.  
  1136. if (a == 5) {
  1137.   puts("a == 5 on tosi");
  1138.   a = 10;
  1139. }
  1140.  
  1141. Jos muuttujan a arvo on 5, tulostaa tekstin "a == 5 on tosi" ja muuttaa  a:n
  1142. arvon 10:ksi. Huomaa, että lausekkeen perässä ei ole ";"-merkkiä,  koska  se
  1143. ei tässä tapauksessa muodosta lausetta. If-rakenne sen sijaan on kokonaisuu-
  1144. tena lause, johon kuuluu  perässä  oleva  toinen  lause  (tässä  tapauksessa
  1145. useamman lauseen muodostama ohjelmalohko). 
  1146.  
  1147. if (a < b) 
  1148.   puts("a on pienempi kuin b");
  1149. else if (a == b) {
  1150.   puts("a on samanarvoinen kuin b");
  1151.   b = 0;
  1152. }
  1153.  
  1154. Tässä tapuksessa on ensimmäisen if:n ja else:n jälkeiset aaltosulkeet  voitu
  1155. jättää pois, toisen if:n jälkeen ei. Tämän voisi kirjoittaa myös  jättämättä
  1156. aaltosulkeita pois:
  1157.  
  1158. if (a < b) {
  1159.   puts("a on pienempi kuin b");
  1160. } else {
  1161.   if (a == b) {
  1162.     puts("a on samanarvoinen kuin b");
  1163.     b = 0;
  1164.   }
  1165. }
  1166.  
  1167. Jotkut  käyttävät  aina  aaltosulkeita,  vaikka  niitä  ei  tarvittaisikaan.
  1168. Tässäkin tapauksessa on havaittavissa, että se voi selkeyttää hieman  koodin
  1169. rakennetta.
  1170.  
  1171. C-kielen grammatiikan ainoa epäselvyys on useamman vailla aaltosulkeita ole-
  1172. van if:n jälkeen tulevan else:n tapaus. (Jos joku tietää, miten välttää par-
  1173. serissa  tämän  takia  ilmenevän  shift/reduce-conflictin  keksimättä   omia
  1174. ylimääräisiä sääntöjään ja monimutkaistamatta parseria pahemmin, niin kerto-
  1175. koon). Jos meillä on esimerkiksi: 
  1176.  
  1177. if (b != 10)
  1178.   if (a)
  1179.     puts("text1");
  1180.   else
  1181.     puts("text2");
  1182.  
  1183. Tämä näyttää selkeältä (erityisesti muotoilun ansiosta), mutta sisältää kui-
  1184. tenkin epäselvyyden. Periaatteessa else voisi olla kummalle  tahansa  if-eh-
  1185. dolle vaihtoehto. Tämä kuitenkin tulkitaan siten (kuten esimerkin muotoilus-
  1186. sa on otettu huomioon), että else on vaihtoehtona aina sisimmälle  mahdolli-
  1187. selle if-ehdolle. Hyvä tapa  on  kuitenkin  näissä  epäselvissä  tapauksissa
  1188. käyttää aaltosulkeita: 
  1189.  
  1190. if (b != 10) {
  1191.   if (a)
  1192.     puts("text1");
  1193.   else
  1194.     puts("text2");
  1195. }
  1196.  
  1197. Tästä käy myös ilmi, että if:n ehdon ei tarvitse sisältää vertailuoperaatto-
  1198. reita. Tässä sisempi if testaa, onko muuttujan  a  arvo  tosi  vai  ei,  eli
  1199. "text2" tulostuu, jos a on 0, muuten tulostetaan "text1".
  1200.  
  1201.  
  1202. {3Ensimmäinen osa päättyy...
  1203.  
  1204. Tähän asti en ole voinut esittää useampia kokonaisia esimerkkiohjelmia, kos-
  1205. ka annettu tieto itse kielestä on vielä hyvin vähäistä.  Myöhemmissä  osissa
  1206. näitä tulee olemaan enemmän. Tarkoitus on käsitellä ainakin seuraavia aihei-
  1207. ta jatkossa:
  1208.  
  1209.     - loogiset operaatiot (&&, ||, !)
  1210.     - operaattoreiden lyhenteitä
  1211.     - silmukat (for, while, do { } while)
  1212.     - switch
  1213.     - esikäsittelyn ohjaaminen
  1214.     - lisää tietoa tyypeistä, muuttujista ja funktioista
  1215.     - main()-funktion parametrit
  1216.     - merkkijono- ja merkkivakiot
  1217.     - lisää operaattoreita (*, &, ->, ., ?:, ",")
  1218.     - operaatioiden suoritusjärjestys
  1219.     - liukuluvut, liukulukuvakiot
  1220.     - goto-komento, miksi ei pidä käyttää
  1221.     - standardeja (ANSI) C-funktioita ja include-tiedostoja, niiden käyttö
  1222.     - tiedon käsittelytekniikkaa (muisti, tiedostot, muuttujat)
  1223.     - käännöksen vaiheet
  1224.     - suuremman projektin kasassapito
  1225.     - C-kääntäjän toimintaa: C-kielen teoriaa
  1226.     - bugien etsintä
  1227.     - C-laajennuksia
  1228.     - ohjelmointitekniikka: vihjeitä
  1229.     - Amigan käyttöjärjestelmä: alustavaa tietoa, mistä jatkaa
  1230.